package cocurrent;

import org.junit.Test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockTest {
    Lock lock = new ReentrantLock(true);//是否公平锁
    CountDownLatch countDownLatch = new CountDownLatch(2);

    /**
     * countDownLatch线程同步的应用 ，   lock锁 tryLock的应用
     *
     * @throws InterruptedException
     */
    @Test
    public void test1() throws InterruptedException {
        Thread thread = new Thread(() -> {
            testMethod();
            System.out.println("thread1 out~~");
            countDownLatch.countDown();

        });
        thread.start();

        Thread thread2 = new Thread(() -> {
            testMethod();
            System.out.println("thread2 out~~");
            countDownLatch.countDown();
        });
        thread2.start();
        countDownLatch.await();

    }

    public void testMethod() {
        boolean locked = false;
        try {
//            lock.lock();
            locked = lock.tryLock();//尝试去锁定
            System.out.println(locked);
            if (locked)
                TimeUnit.SECONDS.sleep(5);
        } catch (Exception e) {

        } finally {
            if (locked) {
                lock.unlock();
            }
        }

    }

    /**
     * 打断等待锁的线程
     *
     * @throws InterruptedException
     */
    @Test
    public void test2() throws InterruptedException {
        Thread thread = new Thread(() -> {
            try {
                lock.lockInterruptibly();
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
            System.out.println("thread1 out~~");
            countDownLatch.countDown();

        });
        thread.start();

        Thread thread2 = new Thread(() -> {
            try {
                lock.lockInterruptibly();
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
            System.out.println("thread2 out~~");
            countDownLatch.countDown();
        });
        thread2.start();
        TimeUnit.SECONDS.sleep(2);
        thread2.interrupt();
        countDownLatch.await();

    }

}
